class MyPromise {
  constructor(func) {
    this.callbackList = []
    this.callIndex = 0
    this.status = 0
    this.data = ''
    const getOne = () => {
      if (this.callIndex >= this.callbackList.length) {
        return null
      }
      const ret = this.callbackList[this.callIndex++]
      return ret
    }

    const invokeCallback = (status, res) => {
      const func = getOne()
      this.status = status
      this.data = res
      if (func) {
        if (func.status === status) {
          res = func.callback(res)
          if (res && res instanceof MyPromise) {
            invokeCallback(res.status, res.data)
            return
          }
          invokeCallback(1, res)
        } else {
          invokeCallback(status, res)
        }
      }
    }

    const resolve = (res) => {
      invokeCallback(1, res)
    }

    const reject = (err) => {
      invokeCallback(2, err)
    }

    this.status = 0 // pendding
    setTimeout(() => {
      try {
        func(resolve, reject)
      } catch (ex) {
        reject(ex)
      }
    }, 0)
  }

  static reject(err) {
    const rt = new MyPromise((resolve, reject) => {
    })
    rt.status = 2
    rt.data = err
    return rt
  }

  static resolve(res) {
    const rt = new MyPromise((resolve, reject) => {
    })
    rt.status = 1
    rt.data = res
    return rt
  }

  then(callback) {
    this.callbackList.push({ callback, status: 1 })
    return this
  }

  catch(callback) {
    this.callbackList.push({ callback, status: 2 })
    return this
  }
}

new MyPromise((res, reject) => {
  res('hello')
}).then(data => {
  console.log(data)
})
